package com.rayboo.example.serializable;

import java.io.*;

/**
 * Transient的作用及使用方法
 *
 * <p>(1）一旦变量被transient修饰，变量将不再是对象持久化的一部分，该变量内容在序列化后无法获得访问。
 *    (2）transient关键字只能修饰变量，而不能修饰方法和类。注意，本地变量是不能被transient关键字修饰的。
 *    变量如果是用户自定义类变量，则该类需要实现Serializable接口。
 *    (3）被transient关键字修饰的变量不再能被序列化，一个静态变量不管是否被transient修饰，均不能被序列化。
 *
 * <p>https://www.jianshu.com/p/056dc2a53773
 * <p>https://stackoverflow.com/questions/910374/why-does-java-have-transient-fields
 */
public class TransientExample {

    static class Rectangle implements Serializable {
        private static final long serialVersionUID = 5942269665140550507L;
        private Integer width;
        private Integer height;
        private transient Integer area;

        public Rectangle(Integer width, Integer height) {
            this.width = width;
            this.height = height;
            this.area = width * height;
        }

        public void setArea() {
            this.area = this.width * this.height;
        }

        @Override
        public String toString() {
            StringBuffer sb = new StringBuffer(40);
            sb.append("width : ");
            sb.append(this.width);
            sb.append("\nheight : ");
            sb.append(this.height);
            sb.append("\narea : ");
            sb.append(this.area);
            return sb.toString();
        }
    }

    public static void main(String args[]) throws Exception {
        Rectangle rectangle = new Rectangle(3, 4);
        System.out.println("1.原始对象\n" + rectangle);

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("rectangle"));
        // 往流写入对象
        out.writeObject(rectangle);
        out.close();

        // 从流读取对象
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("rectangle"));
        Rectangle readObject = (Rectangle) in.readObject();

        System.out.println("2.反序列化后的对象\n" + readObject);
        readObject.setArea();

        System.out.println("3.恢复成原始对象\n" + readObject);
        in.close();
    }
}
